﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using YioksPlanEditor.ObjectCopy;

namespace YioksPlanEditor.Tools.Web
{
    public class MyIEplorer : Model
    {
        #region  属性

        #region Cookie容器
        /// <summary>
        /// Cookie容器
        /// </summary>
        public CookieContainer Cookies { get; set; } = new CookieContainer();
        #endregion

        #region 浏览器代理
        /// <summary>
        /// 用户代理
        /// </summary>
        public string Agent { get; set; } = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 MK/" + Guid.NewGuid().ToString("D");
        #endregion

        #region 超时时间（秒）
        /// <summary>
        /// 超时时间（秒）
        /// </summary>
        public int Timeout { get; set; } = 30;
        #endregion

        #region 引用页
        /// <summary>
        /// 引用页
        /// </summary>
        public string Referer { get; set; } = "";
        #endregion

        #endregion

        #region 构造函数

        public MyIEplorer()
        {
            SetDefaultProp("Cookies", new CookieContainer());
            SetDefaultProp("Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 MK/" + Guid.NewGuid().ToString("D"));
            SetDefaultProp("Timeout", 30);
            SetDefaultProp("Referer", "");
        }


        #endregion

        #region 方法

        #region Get访问网页
        public WebStatus GetPage(string url, Dictionary<string, string> parameters)
        {
            //请求参数
            var parameter = "";
            foreach (var name in parameters.Keys)
            {
                if (parameter == "")
                    parameter = name + "=" + parameters[name];
                else
                    parameter = parameter + "&" + name + "=" + parameters[name];
            }

            if (!string.IsNullOrEmpty(parameter))
            {
                url = url + "?" + parameter;
            }

            return GetPage(url);

        }

        public WebStatus GetPage(string url)
        {
            var webStatus = new WebStatus
            {
                StateTime = DateTime.Now,
                Url = url,
                Referer = Referer
            };

            HttpWebRequest myHttpWebRequest = null;
            HttpWebResponse myHttpWebResponse = null;
            StreamReader streamReader = null;
            try
            {
                //请求对像
                var uri = new Uri(url);

                #region 参数处理
                try
                {
                    var parameter = uri.Query;
                    if (parameter.Length > 0)
                    {
                        if (parameter.Substring(0, 1) == "?")
                            parameter = parameter.Remove(0, 1);
                        var parameters = parameter.Split('&');
                        for (var i = 0; i < parameters.Length; i++)
                        {
                            var query = parameters[i].Split('=');
                            try
                            {
                                webStatus.Parameter[query[0]] = "";
                                try
                                {
                                    webStatus.Parameter[query[0]] = query[1];
                                }
                                catch (Exception ex) { LogTool.Log(ex); }
                            }
                            catch (Exception ex) { LogTool.Log(ex); }
                        }
                    }
                }
                catch (Exception ex) { LogTool.Log(ex); }
                #endregion

                myHttpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
                myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
                myHttpWebRequest.Method = "GET";
                myHttpWebRequest.CookieContainer = Cookies;
                myHttpWebRequest.Referer = Referer;
                myHttpWebRequest.Timeout = Timeout * 1000;
                myHttpWebRequest.AllowAutoRedirect = true;
                myHttpWebRequest.UserAgent = Agent;
                myHttpWebRequest.ConnectionGroupName = url;
                myHttpWebRequest.ServicePoint.ConnectionLimit = 100;

                //开始请求
                try
                {
                    myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

                    webStatus.Length = myHttpWebResponse.ContentLength;
                    webStatus.Encoding = myHttpWebResponse.ContentType;

                    if (myHttpWebResponse.ContentType.ToLower().Contains("gzip"))
                        streamReader = new StreamReader(new GZipStream(myHttpWebResponse.GetResponseStream(), CompressionMode.Decompress));
                    else if (myHttpWebResponse.ContentType.ToLower().Contains("utf-8"))
                        streamReader = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.UTF8);
                    else
                        streamReader = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.Default);

                    webStatus.Body = streamReader.ReadToEnd();
                    Referer = url;
                    _SaveCookies(myHttpWebResponse);
                }
                catch (Exception ex)
                {
                    webStatus.ErrInfo = ex.ToString();
                    LogTool.Log(ex);
                }
            }
            catch (Exception ex)
            {
                webStatus.ErrInfo = ex.ToString();
                LogTool.Log(ex);
            }

            if (streamReader != null)
                streamReader.Close();
            if (myHttpWebResponse != null)
                myHttpWebResponse.Close();
            if (myHttpWebRequest != null)
            {
                myHttpWebRequest.ServicePoint.CloseConnectionGroup(url);
                myHttpWebRequest.Abort();
            }

            webStatus.EndTime = DateTime.Now;
            return webStatus;
        }
        #endregion

        #region Post网页
        public WebStatus PostPage(string url, Dictionary<string, string> postParameter)
        {
            //返回值
            var webStatus = new WebStatus
            {
                StateTime = DateTime.Now,
                Url = url,
                Referer = Referer
            };

            //初始化对像
            HttpWebRequest myHttpWebRequest = null;
            HttpWebResponse myHttpWebResponse = null;
            StreamReader streamReader = null;

            //请求参数
            var parameter = "";
            foreach (var name in postParameter.Keys)
            {
                if (parameter == "")
                    parameter = name + "=" + postParameter[name];
                else
                    parameter = parameter + "&" + name + "=" + postParameter[name];
            }
            var parameterBytes = Encoding.Default.GetBytes(parameter);
            webStatus.Parameter = postParameter;

            try
            {
                //请求对像
                myHttpWebRequest = (HttpWebRequest)WebRequest.Create(new Uri(url));
                myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
                myHttpWebRequest.Method = "POST";
                myHttpWebRequest.CookieContainer = Cookies;
                myHttpWebRequest.Referer = Referer;
                myHttpWebRequest.Timeout = Timeout * 1000;
                myHttpWebRequest.AllowAutoRedirect = true;
                myHttpWebRequest.UserAgent = Agent;
                myHttpWebRequest.ContentLength = parameterBytes.Length;
                myHttpWebRequest.ConnectionGroupName = url;
                myHttpWebRequest.ServicePoint.ConnectionLimit = 100;
                myHttpWebRequest.Proxy = new WebProxy("58.47.191.140", 3128);

                //开始请求
                try
                {
                    Stream myRequestStream = myHttpWebRequest.GetRequestStream();
                    myRequestStream.Write(parameterBytes, 0, parameterBytes.Length);
                    myRequestStream.Flush();
                    myRequestStream.Close();

                    myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

                    webStatus.Length = myHttpWebResponse.ContentLength;
                    webStatus.Encoding = myHttpWebResponse.ContentType;

                    if (myHttpWebResponse.ContentType.ToLower().Contains("gzip"))
                        streamReader = new StreamReader(new GZipStream(myHttpWebResponse.GetResponseStream(), CompressionMode.Decompress));
                    else if (myHttpWebResponse.ContentType.ToLower().Contains("utf-8"))
                        streamReader = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.UTF8);
                    else
                        streamReader = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.Default);

                    webStatus.Body = streamReader.ReadToEnd();
                    Referer = url;
                    _SaveCookies(myHttpWebResponse);
                }
                catch (Exception ex)
                {
                    webStatus.ErrInfo = ex.ToString();
                    LogTool.Log(ex);
                }
            }
            catch (Exception ex)
            {
                webStatus.ErrInfo = ex.ToString();
                LogTool.Log(ex);
            }

            if (streamReader != null)
                streamReader.Close();
            if (myHttpWebResponse != null)
                myHttpWebResponse.Close();
            if (myHttpWebRequest != null)
            {
                myHttpWebRequest.ServicePoint.CloseConnectionGroup(url);
                myHttpWebRequest.Abort();
            }

            webStatus.EndTime = DateTime.Now;
            return webStatus;
        }
        #endregion

        #region PostFile网页
        public WebStatus PostFilePage(string url, Dictionary<string, string> postParameter, Dictionary<string, string> postFileParameter)
        {
            //返回值
            var webStatus = new WebStatus
            {
                StateTime = DateTime.Now,
                Url = url,
                Referer = Referer,
                Parameter = postParameter
            };
            foreach (var name in postFileParameter.Keys)
                webStatus.Parameter[name] = postFileParameter[name];

            #region 生成文件结构

            var parameterFileBytes = new List<byte[]>();
            //boundary
            var boundary1 = "------------------------7d" + DateTime.Now.Ticks.ToString("x");
            var boundary2 = "--" + boundary1;
            var boundary3 = "--" + boundary1 + "--";

            try
            {
                //带文件的请求开始
                var postFile = boundary2 + "\r\n";
                parameterFileBytes.Add(Encoding.UTF8.GetBytes(postFile));

                #region 生成参数结构
                if (postParameter.Keys.Count > 0)
                {
                    //参数模板
                    var parameterTpl = "Content-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
                    foreach (var name in postParameter.Keys)
                    {
                        var parameter = string.Format(parameterTpl, name, postParameter[name]);
                        parameterFileBytes.Add(Encoding.UTF8.GetBytes(parameter));
                        //一个参数结束
                        postFile = "\r\n" + boundary2 + "\r\n";
                        parameterFileBytes.Add(Encoding.UTF8.GetBytes(postFile));
                    }
                }
                #endregion

                if (postFileParameter.Keys.Count > 0)
                {
                    var fileCount = 0;
                    foreach (var fileName in postFileParameter.Keys)
                    {
                        fileCount++;
                        //创建一个文件请求头部
                        var filePath = postFileParameter[fileName];
                        postFile = "Content-Disposition: form-data; name=\"" + fileName + "\"; filename=\"" + filePath + "\"";
                        postFile = postFile + "\r\n";
                        //_PostFile = _PostFile + "Content-Type: text/plain";
                        postFile = postFile + "Content-Type: application/octet-stream";
                        postFile = postFile + "\r\n\r\n";
                        parameterFileBytes.Add(Encoding.UTF8.GetBytes(postFile));


                        //创建文件流
                        parameterFileBytes.Add(_FileToByte(filePath));

                        //创建一个文件请求结束
                        postFile = "\r\n";
                        if (fileCount == postFileParameter.Keys.Count)
                            postFile = postFile + boundary3;
                        else
                            postFile = postFile + boundary2;
                        postFile = postFile + "\r\n";
                        parameterFileBytes.Add(Encoding.UTF8.GetBytes(postFile));
                    }
                }
            }
            catch (Exception ex)
            {
                webStatus.ErrInfo = ex.ToString();
                webStatus.EndTime = DateTime.Now;
                LogTool.Log(ex);
                return webStatus;
            }
            #endregion

            //初始化对像
            HttpWebRequest myHttpWebRequest = null;
            HttpWebResponse myHttpWebResponse = null;
            StreamReader streamReader = null;

            try
            {
                //请求对像
                myHttpWebRequest = (HttpWebRequest)WebRequest.Create(new Uri(url));
                myHttpWebRequest.Method = "POST";

                //构造请求头部
                var countType = "multipart/form-data;boundary=";
                countType = countType + boundary1 + "\r\n";
                myHttpWebRequest.ContentType = countType;


                myHttpWebRequest.CookieContainer = Cookies;
                myHttpWebRequest.Referer = Referer;
                myHttpWebRequest.Timeout = Timeout * 1000;
                myHttpWebRequest.AllowAutoRedirect = true;
                myHttpWebRequest.UserAgent = Agent;
                myHttpWebRequest.ConnectionGroupName = url;
                myHttpWebRequest.ServicePoint.ConnectionLimit = 100;

                //请求长度
                myHttpWebRequest.ContentLength = 0;

                foreach (var postByet in parameterFileBytes)
                    myHttpWebRequest.ContentLength = myHttpWebRequest.ContentLength + postByet.Length;


                //开始请求
                try
                {
                    var myRequestStream = myHttpWebRequest.GetRequestStream();


                    foreach (var postByet in parameterFileBytes)
                        myRequestStream.Write(postByet, 0, postByet.Length);


                    myRequestStream.Flush();
                    myRequestStream.Close();

                    myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

                    webStatus.Length = myHttpWebResponse.ContentLength;
                    webStatus.Encoding = myHttpWebResponse.ContentType;

                    if (myHttpWebResponse.ContentType.ToLower().Contains("gzip"))
                        streamReader = new StreamReader(new GZipStream(myHttpWebResponse.GetResponseStream(), CompressionMode.Decompress));
                    else if (myHttpWebResponse.ContentType.ToLower().Contains("utf-8"))
                        streamReader = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.UTF8);
                    else
                        streamReader = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.Default);

                    webStatus.Body = streamReader.ReadToEnd();
                    Referer = url;
                    _SaveCookies(myHttpWebResponse);
                }
                catch (Exception ex)
                {
                    webStatus.ErrInfo = ex.ToString();
                    LogTool.Log(ex);
                }
            }
            catch (Exception ex)
            {
                webStatus.ErrInfo = ex.ToString();
                LogTool.Log(ex);
            }

            if (streamReader != null)
                streamReader.Close();
            if (myHttpWebResponse != null)
                myHttpWebResponse.Close();
            if (myHttpWebRequest != null)
            {
                myHttpWebRequest.ServicePoint.CloseConnectionGroup(url);
                myHttpWebRequest.Abort();
            }

            webStatus.EndTime = DateTime.Now;
            return webStatus;
        }

        #endregion

        #region 下载文件
        public DownloadStatus DownloadFile(string url, string saveFilePath)
        {
            var downloadStatus = new DownloadStatus
            {
                StateTime = DateTime.Now,
                Url = url,
                FilePath = saveFilePath
            };

            HttpWebRequest myHttpWebRequest = null;
            HttpWebResponse myHttpWebResponse = null;
            StreamReader streamReader = null;
            try
            {
                //请求对像
                myHttpWebRequest = (HttpWebRequest)WebRequest.Create(new Uri(url));
                myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
                myHttpWebRequest.Method = "GET";
                myHttpWebRequest.CookieContainer = Cookies;
                myHttpWebRequest.Referer = Referer;
                myHttpWebRequest.Timeout = Timeout * 1000;
                myHttpWebRequest.AllowAutoRedirect = true;
                myHttpWebRequest.UserAgent = Agent;
                myHttpWebRequest.ConnectionGroupName = url;
                myHttpWebRequest.ServicePoint.ConnectionLimit = 100;

                //开始请求
                try
                {
                    myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                    downloadStatus.Length = myHttpWebResponse.ContentLength;
                    downloadStatus = _SaveBinaryFile(myHttpWebResponse, saveFilePath, downloadStatus);
                    Referer = url;
                    _SaveCookies(myHttpWebResponse);
                }
                catch (Exception ex)
                {
                    downloadStatus.ErrInfo = ex.ToString();
                    LogTool.Log(ex);
                }
            }
            catch (Exception ex)
            {
                downloadStatus.ErrInfo = ex.ToString();
                LogTool.Log(ex);
            }

            if (streamReader != null)
                streamReader.Close();
            if (myHttpWebResponse != null)
                myHttpWebResponse.Close();
            if (myHttpWebRequest != null)
            {
                myHttpWebRequest.ServicePoint.CloseConnectionGroup(url);
                myHttpWebRequest.Abort();
            }

            downloadStatus.EndTime = DateTime.Now;
            return downloadStatus;
        }

        public void DownloadFile(string url, string saveFilePath, out DownloadStatus downloadStatus)
        {
            downloadStatus = new DownloadStatus
            {
                StateTime = DateTime.Now,
                Url = url,
                FilePath = saveFilePath
            };

            HttpWebRequest myHttpWebRequest = null;
            HttpWebResponse myHttpWebResponse = null;
            StreamReader streamReader = null;
            try
            {
                //请求对像
                myHttpWebRequest = (HttpWebRequest)WebRequest.Create(new Uri(url));
                myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
                myHttpWebRequest.Method = "GET";
                myHttpWebRequest.CookieContainer = Cookies;
                myHttpWebRequest.Referer = Referer;
                myHttpWebRequest.Timeout = Timeout * 1000;
                myHttpWebRequest.AllowAutoRedirect = true;
                myHttpWebRequest.UserAgent = Agent;
                myHttpWebRequest.ConnectionGroupName = url;
                myHttpWebRequest.ServicePoint.ConnectionLimit = 100;

                //开始请求
                try
                {
                    myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                    downloadStatus.Length = myHttpWebResponse.ContentLength;
                    downloadStatus.Status = DownloadStatus.DlStatus.Download;
                    var buffer = new byte[1024];
                    try
                    {
                        if (File.Exists(saveFilePath))
                            File.Delete(saveFilePath);
                        var outStream = File.Create(saveFilePath);
                        var inStream = myHttpWebResponse.GetResponseStream();
                        int l;
                        do
                        {
                            l = inStream.Read(buffer, 0, buffer.Length);

                            if (l > 0)
                            {
                                downloadStatus.DownloadLength = downloadStatus.DownloadLength + Convert.ToDouble(l) / 1024;
                                outStream.Write(buffer, 0, l);
                            }
                        }
                        while (l > 0);

                        outStream.Close();
                        inStream.Close();

                        downloadStatus.Status = DownloadStatus.DlStatus.Ok;
                    }
                    catch (Exception ex)
                    {
                        downloadStatus.ErrInfo = ex.ToString();
                        LogTool.Log(ex);
                    }
                    Referer = url;
                    _SaveCookies(myHttpWebResponse);
                }
                catch (Exception ex)
                {
                    downloadStatus.ErrInfo = ex.ToString();
                    LogTool.Log(ex);
                }
            }
            catch (Exception ex)
            {
                downloadStatus.ErrInfo = ex.ToString();
                LogTool.Log(ex);
            }

            if (streamReader != null)
                streamReader.Close();
            if (myHttpWebResponse != null)
                myHttpWebResponse.Close();
            if (myHttpWebRequest != null)
            {
                myHttpWebRequest.ServicePoint.CloseConnectionGroup(url);
                myHttpWebRequest.Abort();
            }

            downloadStatus.EndTime = DateTime.Now;
        }

        #endregion

        #endregion

        #region 辅助函数

        #region 保存Cookice值
        private void _SaveCookies(HttpWebResponse myHttpWebResponse)
        {
            //var cookie = myHttpWebResponse.ResponseUri.ToString() + "\r\n";
            for (var i = 0; i < myHttpWebResponse.Cookies.Count; i++)
            {
                Cookies.Add(myHttpWebResponse.Cookies[i]);
            }
            try
            {
                for (var i = 0; i < myHttpWebResponse.Headers.Count; i++)
                {
                    if (myHttpWebResponse.Headers.AllKeys[i].Contains("Set-Cookie"))
                    {
                        var allkeys = myHttpWebResponse.Headers[i].Split(',');
                        for (var m = 0; m < allkeys.Length; m++)
                        {
                            if (allkeys[m].Contains("httponly"))
                            {
                                var setCook = allkeys[m].Split(';');
                                Cookies.SetCookies(new Uri(myHttpWebResponse.ResponseUri.ToString()), allkeys[m]);
                                try
                                {
                                    Cookies.SetCookies(new Uri(myHttpWebResponse.ResponseUri.ToString()), setCook[0]);
                                    for (var j = 0; j < setCook.Length; j++)
                                    {
                                        if (setCook[j].Contains("domain="))
                                        {
                                            var domain = setCook[j].Split('=');
                                            try
                                            {
                                                var a = domain[1].Substring(0, 7);
                                                if (a == "http://")
                                                {
                                                    Cookies.SetCookies(new Uri(domain[1]), setCook[0]);
                                                }
                                                else
                                                {
                                                    a = domain[1].Substring(0, 1);
                                                    if (a == ".")
                                                        Cookies.SetCookies(new Uri("http://" + domain[1].Remove(0, 1)), setCook[0]);
                                                    else
                                                        Cookies.SetCookies(new Uri("http://" + domain[1]), setCook[0]);
                                                }
                                            }
                                            catch (Exception ex) { LogTool.Log(ex); }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    LogTool.Log(ex);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogTool.Log(ex);
            }
        }
        #endregion

        #region 文件转Byte[]
        private static byte[] _FileToByte(string filePath)
        {
            FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            // 读取文件的 byte[]
            byte[] bytes = new byte[fileStream.Length];
            fileStream.Read(bytes, 0, bytes.Length);
            fileStream.Close();
            return bytes;
        }
        #endregion

        #region 错误处理
        private static object[] _GetErrCode(string errMessage)
        {

            object[] _Return = new object[2];
            try
            {
                if (errMessage.Contains("操作超时"))
                { _Return[0] = 101; _Return[1] = "请求超时！"; }

                else if (errMessage.Contains("无法连接到远程服务器"))
                { _Return[0] = 102; _Return[1] = "无法连接到远程服务器！"; }

                else if (errMessage.Contains("无法解析此远程"))
                { _Return[0] = 103; _Return[1] = "无法解析此域名！"; }

                else if (errMessage.Contains("基础连接已经关"))
                { _Return[0] = 104; _Return[1] = "Post服务器失败，请确定服务接收POST数据！"; }

                else if (errMessage.Contains("(400)"))
                { _Return[0] = 400; _Return[1] = "无法解析此请求！"; }

                else if (errMessage.Contains("(401)"))
                { _Return[0] = 401; _Return[1] = "未经授权！"; }

                else if (errMessage.Contains("(403)"))
                { _Return[0] = 403; _Return[1] = "禁止访问！"; }

                else if (errMessage.Contains("(404)"))
                { _Return[0] = 404; _Return[1] = "找不到文件或目录！"; }

                else if (errMessage.Contains("(405)"))
                { _Return[0] = 405; _Return[1] = "用于访问该页的 HTTP 动作未被许可！"; }

                else if (errMessage.Contains("(406)"))
                { _Return[0] = 406; _Return[1] = "客户端浏览器不接受所请求页面的 MIME 类型！"; }

                else if (errMessage.Contains("(407)"))
                { _Return[0] = 407; _Return[1] = "Web 服务器需要初始的代理验证！"; }

                else if (errMessage.Contains("(410)"))
                { _Return[0] = 410; _Return[1] = "文件已删除！"; }

                else if (errMessage.Contains("(412)"))
                { _Return[0] = 412; _Return[1] = "客户端设置的前提条件在 Web 服务器上评估时失败！"; }

                else if (errMessage.Contains("(414)"))
                { _Return[0] = 414; _Return[1] = "请求 URL 太大，因此在 Web 服务器上不接受该 URL！"; }

                else if (errMessage.Contains("(500)"))
                { _Return[0] = 500; _Return[1] = "服务器内部错误！"; }

                else if (errMessage.Contains("(501)"))
                { _Return[0] = 501; _Return[1] = "未能实现请求！"; }

                else { _Return[0] = 999; _Return[1] = "未知错误：" + errMessage.Substring(0, errMessage.IndexOf("在", StringComparison.Ordinal)); }
            }
            catch (Exception ex) { _Return[0] = 999; _Return[1] = "未知错误：" + ex; LogTool.Log(ex); }
            return _Return;
        }
        #endregion

        #region 下载文件
        private DownloadStatus _SaveBinaryFile(WebResponse response, string fileName, DownloadStatus downloadStatus)
        {
            downloadStatus.Status = DownloadStatus.DlStatus.Download;
            byte[] buffer = new byte[1024];
            try
            {
                if (File.Exists(fileName))
                    File.Delete(fileName);
                var outStream = File.Create(fileName);
                var inStream = response.GetResponseStream();
                int length;
                do
                {
                    if (inStream != null)
                    {
                        length = inStream.Read(buffer, 0, buffer.Length);
                    }
                    else { length = 0; }

                    if (length > 0)
                    {
                        outStream.Write(buffer, 0, length);
                        downloadStatus.DownloadLength = downloadStatus.DownloadLength + length;
                    }
                }
                while (length > 0);

                outStream.Close();
                inStream?.Close();

                downloadStatus.Status = DownloadStatus.DlStatus.Ok;
            }
            catch (Exception ex)
            {
                downloadStatus.ErrInfo = ex.ToString();
                LogTool.Log(ex);
            }
            return downloadStatus;
        }
        #endregion

        #endregion

        #region 请求返回对像
        public class WebStatus : Model
        {
            #region 网页大小
            /// <summary>
            /// 网页大小
            /// </summary>
            public long Length { set; get; }
            #endregion

            #region 网页地址
            /// <summary>
            /// 网页地址
            /// </summary>
            public string Url { set; get; } = "";
            #endregion

            #region 引用页
            /// <summary>
            /// 引用页
            /// </summary>
            public string Referer { get; set; } = "";
            #endregion

            #region 打开网页花费时间 单位秒
            /// <summary>
            /// 打开网页花费时间 单位秒
            /// </summary>
            public double Time { private set; get; }
            #endregion

            #region 开始时间
            /// <summary>
            /// 开始时间
            /// </summary>
            public DateTime StateTime { set; get; } = DateTime.Now;
            #endregion

            #region 结束时间
            private DateTime _endTime = DateTime.Now;
            /// <summary>
            /// 结束时间
            /// </summary>
            public DateTime EndTime
            {
                set
                {
                    _endTime = value;
                    var timeSpan = EndTime - StateTime;
                    Time = timeSpan.TotalSeconds;
                }
                get { return _endTime; }
            }
            #endregion

            #region 请求状态
            /// <summary>
            /// 请求状态
            /// </summary>
            public bool Status { private set; get; } = true;
            #endregion

            #region 错误代码
            private int _errCode;
            /// <summary>
            /// 错误代码
            /// </summary>
            public int ErrCode
            {
                private set
                {
                    _errCode = value;
                    if (ErrCode != 0)
                        Status = false;
                }
                get { return _errCode; }
            }
            #endregion

            #region 错误内容
            private string _errInfo = "";
            /// <summary>
            /// 错误内容
            /// </summary>
            public string ErrInfo
            {
                set
                {
                    if (value.Trim() != "")
                    {
                        var errMessage = _GetErrCode(value.Trim().ToLower());
                        ErrCode = (int)errMessage[0];
                        _errInfo = (string)errMessage[1];
                    }
                    else
                        _errInfo = value;
                }
                get { return _errInfo; }
            }
            #endregion

            #region 页面内容
            /// <summary>
            /// 页面内容
            /// </summary>
            public string Body { set; get; } = "";
            #endregion

            #region 页面编码
            /// <summary>
            /// 页面编码
            /// </summary>
            public string Encoding { set; get; } = "";
            #endregion

            #region 请求参数
            /// <summary>
            /// 请求参数
            /// </summary>
            public Dictionary<string, string> Parameter { set; get; } = new Dictionary<string, string>();
            #endregion

            public WebStatus()
            {
                SetDefaultProp("Length", 0);
                SetDefaultProp("Url", "");
                SetDefaultProp("Referer", "");
                SetDefaultProp("Time", 0);
                SetDefaultProp("StateTime", DateTime.Now);
                SetDefaultProp("Status", true);
                SetDefaultProp("Body", "");
                SetDefaultProp("Encoding", "");
                SetDefaultProp("Parameter", new Dictionary<string, string>());
            }
        }
        #endregion

        #region 下载返回对像
        public class DownloadStatus : Model
        {
            public enum DlStatus
            {
                Download,
                Query,
                False,
                Ok,
            }

            #region 下载网址

            /// <summary>
            /// 下载网址
            /// </summary>
            public string Url { set; get; } = "";

            #endregion

            #region 文件保存路径
            /// <summary>
            /// 文件保存路径
            /// </summary>
            public string FilePath { set; get; } = "";
            #endregion

            #region 文件大小 KB
            private double _length;
            /// <summary>
            /// 文件大小 KB
            /// </summary>
            public double Length
            {
                set { _length = value / 1024; }
                get { return _length; }
            }
            #endregion

            #region 已下载文件大小 KB
            private double _downloadLength;
            /// <summary>
            /// 已下载文件大小 KB
            /// </summary>
            public double DownloadLength
            {
                set
                {
                    _downloadLength = value;

                    #region 设置下载花费时间
                    if (EndTime == Convert.ToDateTime("2001-01-01"))
                    {
                        var timeSpan = DateTime.Now - StateTime;
                        DownloadTime = timeSpan.TotalSeconds;
                    }
                    #endregion


                    //计算下载进度
                    try
                    {
                        DownloadProgress = (Convert.ToDouble(DownloadLength) / Convert.ToDouble(Length)) * 100;
                    }
                    catch (Exception ex) { LogTool.Log(ex); }

                    //计算下载速度
                    try
                    {
                        DownloadSpeed = Convert.ToDouble(DownloadLength) / Convert.ToDouble(DownloadTime);
                    }
                    catch (Exception ex) { LogTool.Log(ex); }

                    //计算剩余下载时间
                    try
                    {
                        DownloadEndTime = Convert.ToDouble(Length - DownloadLength) / DownloadSpeed;
                    }
                    catch (Exception ex) { LogTool.Log(ex); }
                }
                get { return _downloadLength; }
            }
            #endregion

            #region 下载进度 %
            /// <summary>
            /// 下载进度 %
            /// </summary>
            public double DownloadProgress { private set; get; }
            #endregion

            #region 下载速度 KB/S
            /// <summary>
            /// 下载速度 KB/S
            /// </summary>
            public double DownloadSpeed { private set; get; }
            #endregion

            #region 剩余下载时间 秒
            /// <summary>
            /// 剩余下载时间 秒
            /// </summary>
            public double DownloadEndTime { private set; get; }
            #endregion

            #region 下载花费时间 秒
            /// <summary>
            /// 下载花费时间 秒
            /// </summary>
            public double DownloadTime { private set; get; }
            #endregion

            #region 开始时间
            /// <summary>
            /// 开始时间
            /// </summary>
            public DateTime StateTime { set; get; } = DateTime.Now;
            #endregion

            #region 结束时间
            private DateTime _endTime = Convert.ToDateTime("2001-01-01");
            /// <summary>
            /// 结束时间
            /// </summary>
            public DateTime EndTime
            {
                set
                {
                    _endTime = value;
                    var timeSpan = EndTime - StateTime;
                    DownloadTime = timeSpan.TotalSeconds;
                }
                get { return _endTime; }
            }
            #endregion

            #region 下载状态
            private DlStatus _status = DlStatus.Query;
            /// <summary>
            /// 下载状态
            /// </summary>
            public DlStatus Status
            {
                set
                {
                    _status = value;
                    if (_status != DlStatus.Ok) return;
                    DownloadEndTime = 0;
                    DownloadLength = Length;
                    DownloadProgress = 100;
                }
                get { return _status; }
            }
            #endregion

            #region 错误代码
            private int _errCode;
            /// <summary>
            /// 错误代码
            /// </summary>
            public int ErrCode
            {
                private set
                {
                    _errCode = value;
                    if (ErrCode != 0)
                        Status = DlStatus.False;
                }
                get { return _errCode; }
            }
            #endregion

            #region 错误内容
            private string _errInfo = "";
            /// <summary>
            /// 错误内容
            /// </summary>
            public string ErrInfo
            {
                set
                {
                    if (value.Trim() != "")
                    {
                        var errMessage = _GetErrCode(value.Trim().ToLower());
                        ErrCode = (int)errMessage[0];
                        _errInfo = (string)errMessage[1];
                    }
                    else
                        _errInfo = value;
                }
                get { return _errInfo; }
            }
            #endregion

            public DownloadStatus()
            {
                SetDefaultProp("Url", "");
                SetDefaultProp("FilePath", "");
                SetDefaultProp("DownloadProgress", 0);
                SetDefaultProp("DownloadSpeed", 0);
                SetDefaultProp("DownloadEndTime", 0);
                SetDefaultProp("DownloadTime", 0);
                SetDefaultProp("StateTime", DateTime.Now);
            }
        }
        #endregion
    }

}
